#ifndef XSENDER_HPP
#define XSENDER_HPP

#include "xsignal/signal.hpp"
#include <XReciver.hpp>

//信号发射者
class XSender:public SIG::sigReciver{
public:
	XSender(XReciver *reciver):m_reciver(reciver){};

	void AttachsignalSlot(){
		SIG::connect(this,&XSender::signalTest1,m_reciver,SIG::utils::xOverLoad<void(int)>::of(&XReciver::slot1),SIG::connectType::queueConnection);						//验证绑定成员函数
		SIG::connect(this,&XSender::signalTest1,m_reciver,SIG::utils::xOverLoad<void(int)>::of(&XReciver::slot1),SIG::connectType::queueConnection);						//重复绑定成员函数
		
		SIG::connect(this,&XSender::signalTest2,m_reciver,&XReciver::slot2,SIG::connectType::queueBlockConnection);				//阻塞队列链接
		SIG::connect(this,&XSender::signalTest2,m_reciver,SIG::utils::xOverLoad<void(int,int)>::of(&XReciver::slot1),SIG::connectType::queueConnection);	
		
		SIG::connect(this,&XSender::signalTest_direct,m_reciver,&XReciver::slot_direct,SIG::connectType::directConnection);		//直连绑定

		SIG::connect(this,&XSender::signalTest3,m_reciver,&XReciver::slot6,SIG::connectType::queueConnection);						//绑定成员函数
		SIG::connect(this,&XSender::signalDisconnect,this,[this](){
				SIG::disconnect(this,&XSender::signalTest3,m_reciver,&XReciver::slot6,SIG::connectType::queueConnection); 			//解绑成员函数
		},SIG::connectType::queueConnection);		//绑定成员函数

		//绑定函数对象
		SIG::connect(this,&XSender::signalTest4,[](int t1,int t2,int t3,float t4){
			std::unique_lock lock(XReciver::s_mutex);
			std::cout<<"thrdID:"<<std::this_thread::get_id()<<" lambda [](int t1,int t2,int t3,float t4){} "
			<<t1 <<" "<<t2<<" "<<t3<<" "<<t4<<std::endl;
		},SIG::connectType::queueConnection);

		SIG::connect(this,&XSender::signalTest4,[](int t1,int t2,int t3,float t4){
			std::unique_lock lock(XReciver::s_mutex);
			std::cout<<"lambda enter!"<<std::endl;
			std::cout<<"thrdID:"<<std::this_thread::get_id()<<" lambda [](int t1,int t2,int t3,float t4){} "
			<<t1 <<" "<<t2<<" "<<t3<<" "<<t4<<std::endl;
			std::this_thread::sleep_for(std::chrono::seconds(2));
			std::cout<<"lambda leave!"<<std::endl;
		},SIG::connectType::queueBlockConnection);

		//绑定全局函数
		SIG::connect(this,&XSender::signalTest5,&XSender::slotFun,SIG::connectType::queueConnection);
		SIG::connect(this,&XSender::signalDisconnectGlobalFun,[this](){
				SIG::disconnect(this,&XSender::signalTest5,&XSender::slotFun,SIG::connectType::queueConnection); 	//解绑成员函数
		},SIG::connectType::queueConnection);

	}

	void testRepeatConnect(){
		xemit(signalTest1)(10);
	}

	void testQueBlockConnect(){
		xemit(signalTest2)(10,20);
	}
	
	void testDirecrConnect(){
		xemit(signalTest_direct)(50);
	}

	void testEmitLambdaSignal(){
		xemit(signalTest4)(10,20,30,10.25);
	}
	
	void tesEmitGlobalFunSignal(){
		xemit(signalTest5)(30,31);
	}
	
	void testSignalEmitDisconnectGlobalFun(){
		//解绑全局函数信号槽绑定
		std::cout<<"disconnect global fun!"<<std::endl;
		xemit(signalDisconnectGlobalFun)();
	}
	
	void testEmitThrdStopSignal(){
		xemit(signalStop)();
	}

	void testEmitSigalTest3(){
		xemit(signalTest3)(50);
	}

	void testEmitSignalDisConnect(){
		std::cout<<"disconnect member fun!"<<std::endl;
		xemit(signalDisconnect)();
	}

//测试作为普通函数指针作为槽函数
static void slotFun(int t1,int t2){
	std::unique_lock lock(XReciver::s_mutex);
	std::cout<<"thrdID:"<<std::this_thread::get_id()<<" "<<__FUNCTION__<<" "<<t1 <<" "<<t2<<std::endl;
}
private:
	XSIGNAL(signalTest1,int);
	XSIGNAL(signalTest_direct,int);
	XSIGNAL(signalTest3,int);
	XSIGNAL(signalTest2,int,int);
	XSIGNAL(signalTest4,int,int,int,float);
	XSIGNAL(signalTest5,int,int);

public:
	XSIGNAL(signalStop);
	XSIGNAL(signalDisconnect);
	XSIGNAL(signalDisconnectGlobalFun);
private:
	XReciver* m_reciver;
};
#endif